package ginhelp

import (
	"fmt"
	"gitee.com/luotian110/lt-go-lib/logger"
	"gitee.com/luotian110/lt-go-lib/nethelp"
	"gitee.com/luotian110/lt-go-lib/resp"
	"github.com/gin-gonic/gin"
	"log"
	"net/http"
	"runtime/debug"
)

func Handle404() gin.HandlerFunc {
	return func(c *gin.Context) {
		resp.Err(c, http.StatusNotFound, "接口或者页面路径错误", nil)
		c.Abort()
		return
	}
}

func Handle500() gin.HandlerFunc {
	return func(c *gin.Context) {
		defer func() {
			if r := recover(); r != nil {
				//打印错误堆栈信息
				log.Printf("------>panic: %v\n", r)
				debug.PrintStack()
				//封装通用json返回
				resp.Err500(c, "服务器内部错误")
				c.Abort()
				return
			}
		}()
		//加载完 defer recover，继续后续接口调用
		c.Next()
	}
}

// HandleCross 允许使用跨域请求
func HandleCross() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		method := ctx.Request.Method
		origin := ctx.Request.Header.Get("Origin") //请求头部
		if origin != "" {
			//接收客户端发送的origin （重要！）
			ctx.Header("Access-Control-Allow-Origin", "*") // 可将将 * 替换为指定的域名
			//服务器支持的所有跨域请求的方法
			ctx.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
			//允许跨域设置可以返回其他子段，可以自定义字段
			ctx.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
			// 允许浏览器（客户端）可以解析的头部 （重要）
			ctx.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
			//设置缓存时间
			ctx.Header("Access-Control-Max-Age", "172800")
			//允许客户端传递校验信息比如 cookie (重要)
			ctx.Header("Access-Control-Allow-Credentials", "true")
			ctx.Set("content-type", "application/json")
		}
		if method == "OPTIONS" {
			ctx.JSON(http.StatusOK, "ok!")
		}
		defer func() {
			if err := recover(); err != nil {
				logger.Log.Error(fmt.Sprintf("Panic info is: %v", err))
			}
		}()
		ctx.Next()
	}
}

// ExternalNetworkInterceptor 外网ip拦截器，只允许本地ip访问
func ExternalNetworkInterceptor() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		ip := nethelp.GetRequestIP(ctx)
		if nethelp.IsLocalIp(ip) {
			ctx.Next()
		} else {
			ctx.AbortWithStatus(http.StatusUnauthorized)
			return
		}
	}
}
